package com.tanhua.server.service;


import cn.hutool.core.collection.CollUtil;
import com.tanhua.commons.utils.Constants;
import com.tanhua.dubbo.api.CommentApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.enums.CommentType;
import com.tanhua.model.mongo.Comment;
import com.tanhua.model.vo.CommentVo;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.PageResult;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.interceptor.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class CommentService {
    @DubboReference
    private CommentApi commentApi;
    @DubboReference
    private UserInfoApi userInfoApi;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private MqMessageService mqMessageService;

    /**
     * 评论发布
     *
     * @param movementId
     * @param comment
     */
    public void comments(String movementId, String comment) {
        //从线程中获取用户id
        Long userId = UserHolder.getUserId();
        //构造Comment
        Comment comment1 = new Comment();
        //设置动态id
        comment1.setPublishId(new ObjectId(movementId));
        //设置评论类型
        comment1.setCommentType(CommentType.COMMENT.getType());
        //设置评论人
        comment1.setUserId(userId);
        //设置评论内容
        comment1.setContent(comment);
        //设置发表时间
        comment1.setCreated(System.currentTimeMillis());
        //调用API保存评论C，获取查看评论的数量
        Integer commentCount = commentApi.save(comment1);
        //生成日志登录
        mqMessageService.sendLogMessage(userId, "0205", "movement", null);
        log.info("当前评论数量：" + commentCount);
    }

    /**
     * 评论查询
     *
     * @param movementId
     * @param page
     * @param pageseze
     * @return
     */
    public PageResult findComments(String movementId, Integer page, Integer pageseze) {
        //通过调用API查询评论列表
        List<Comment> list = commentApi.findComments(movementId, CommentType.COMMENT, page, pageseze);
        //判断评论列表是否为空
        if (CollUtil.isEmpty(list)) {
            //如果为空，返回空对象
            return new PageResult();
        }
        //获取用户id
        List<Long> userIds = CollUtil.getFieldValues(list, "userId", Long.class);
        //根据用户id查询用户详情
        Map<Long, UserInfo> map = userInfoApi.findByIds(userIds, null);
        //构造vo对象
        List<CommentVo> vos = new ArrayList<>();
        for (Comment comment : list) {
            //通过id获取用户详情
            UserInfo userInfo = map.get(comment.getUserId());
            //判断时间表是否为空
            if (userInfo != null) {
                CommentVo vo = CommentVo.init(userInfo, comment);
                String key = Constants.COMMENT_INTERACT_KEY + comment.getId().toHexString();
                String hashKey=Constants.COMMENT_LIKE_HASHKEY+UserHolder.getUserId();
                if (redisTemplate.opsForHash().hasKey(key,hashKey)){
                    vo.setHasLiked(1);
                }
                vos.add(vo);
            }
        }
        // 返回结果
        return new PageResult(page, pageseze, vos.size(), vos);
        /*//通过调用API查询评论列表
        List<Comment> list = commentApi.findComments(movementId, CommentType.COMMENT, page, pageseze);
        //判断评论列表是否为空
        if (CollUtil.isEmpty(list)) {
            //如果为空，返回空对象
            return new PageResult();
        }
        //获取用户id
        List<Long> userIds = CollUtil.getFieldValues(list, "userId", Long.class);
        //根据用户id查询用户详情
        Map<Long, UserInfo> map = userInfoApi.findByIds(userIds, null);
        //构造vo对象
        List<CommentVo> vos = new ArrayList<>();
        for (Comment comment : list) {
            UserInfo userInfo = map.get(comment.getUserId());
            //判断时间表是否为空
            if (userInfo!=null){
                CommentVo vo = CommentVo.init(userInfo, comment);
                vos.add(vo);
            }
        }
        //返回结果
        return new PageResult(page,pageseze,0,vos);*/
    }

    /**
     * 动态点赞
     *
     * @param movementId
     * @return
     */
    public Integer like(String movementId) {
        //通过Api查看是否已点赞
        Boolean hasComment = commentApi.hasComment(movementId, UserHolder.getUserId(), CommentType.LIKE);
        if (hasComment) {
            //如果未点赞，抛异常
            throw new BusinessException(ErrorResult.likeError());
        }
        //调用api将数据保存到Mongodb
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(movementId));
        comment.setUserId(UserHolder.getUserId());
        comment.setCommentType(CommentType.LIKE.getType());
        comment.setCreated(System.currentTimeMillis());
        Integer count = commentApi.save(comment);
        //拼接redis的key 将用户的点赞状态存入redis中
        String key = Constants.MOVEMENTS_INTERACT_KEY + movementId;
        String hashKey = Constants.MOVEMENT_LIKE_HASHKEY + UserHolder.getUserId();
        //生成日志登录
        mqMessageService.sendLogMessage(UserHolder.getUserId(), "0203", "movement", null);
        redisTemplate.opsForHash().put(key, hashKey, "1");
        return count;
    }

    /**
     * 取消点赞
     *
     * @param movementId
     * @return
     */
    public Integer dislike(String movementId) {
        //通过Api查看是否已点赞
        Boolean hasComment = commentApi.hasComment(movementId, UserHolder.getUserId(), CommentType.LIKE);
        //如果未点赞，抛异常
        if (!hasComment) {
            throw new BusinessException(ErrorResult.disLikeError());
        }
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(movementId));
        comment.setUserId(UserHolder.getUserId());
        comment.setCommentType(CommentType.LIKE.getType());
        comment.setCreated(System.currentTimeMillis());
        //调用api删除数据，返回点赞数
        Integer count = commentApi.delete(comment);

        //拼接redis的key 将用户的点赞状态存入redis中
        String key = Constants.MOVEMENTS_INTERACT_KEY + movementId;
        String hashKey = Constants.MOVEMENT_LIKE_HASHKEY + UserHolder.getUserId();
        //生成日志登录
        mqMessageService.sendLogMessage(UserHolder.getUserId(), "0206", "movement", null);
        //拼接redis的key，删除点赞状态。
        redisTemplate.opsForHash().delete(key, hashKey);
        return count;
    }

    /**
     * 动态喜欢
     *
     * @param movementId
     * @return
     */
    public Integer love(String movementId) {
        //通过Api查看是否已点赞
        Boolean hasComment = commentApi.hasComment(movementId, UserHolder.getUserId(), CommentType.LOVE);
        //如果未点赞，抛异常
        if (hasComment) {
            throw new BusinessException(ErrorResult.loveError());
        }
        //调用api将数据保存到Mongodb
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(movementId));
        comment.setCommentType(CommentType.LOVE.getType());
        comment.setUserId(UserHolder.getUserId());
        comment.setCreated(System.currentTimeMillis());
        //调用api，返回喜欢数量
        Integer count = commentApi.save(comment);
        //拼接redis的key 将用户的点赞状态存入redis中
        String key = Constants.MOVEMENTS_INTERACT_KEY + movementId;
        String hashKey = Constants.MOVEMENT_LOVE_HASHKEY + UserHolder.getUserId();
        //生成日志登录
        mqMessageService.sendLogMessage(UserHolder.getUserId(), "0204", "movement", null);
        //调用redis方法
        redisTemplate.opsForHash().put(key, hashKey, "1");
        return count;
    }

    /**
     * 取消喜欢
     *
     * @param movementId
     * @return
     */
    public Integer unlove(String movementId) {
        //调用api，判断是否已经喜欢
        Boolean aBoolean = commentApi.hasComment(movementId, UserHolder.getUserId(), CommentType.LOVE);
        if (!aBoolean) {
            throw new BusinessException(ErrorResult.disloveError());
        }
        //如果已经喜欢就删除数据
        //创建comment
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(movementId));
        comment.setCommentType(CommentType.LOVE.getType());
        comment.setUserId(UserHolder.getUserId());
        comment.setCreated(System.currentTimeMillis());
        //生成日志登录
        mqMessageService.sendLogMessage(UserHolder.getUserId(), "0207", "movement", null);
        //调用api 删除数据,返回数量
        Integer count = commentApi.delete(comment);
        //拼接redis的key 将用户的点赞状态存入redis中
        String key = Constants.MOVEMENTS_INTERACT_KEY + movementId;
        String hashKey = Constants.MOVEMENT_LOVE_HASHKEY + UserHolder.getUserId();
        redisTemplate.opsForHash().delete(key, hashKey);

        return count;
    }

    /**
     * 评论点赞
     *
     * @param movementId
     * @return
     */
    public Integer pingLunLike(String movementId) {
        //查询是否已经点赞
        String key = Constants.COMMENT_INTERACT_KEY + movementId;
        String redisKey = Constants.COMMENT_LIKE_HASHKEY + UserHolder.getUserId();
        Boolean aBoolean = redisTemplate.opsForHash().hasKey(key, redisKey);
        if (aBoolean){
            throw new BusinessException(ErrorResult.disLikeError());
        }
        //调用api保存点赞数据
        Integer count = commentApi.pingLunLike(movementId);
        //调用redis方法
        redisTemplate.opsForHash().put(key, redisKey, "1");
        return count;
    }

    /**
     * 取消评论点赞
     * @param movementId
     * @return
     */
    public Integer disLike(String movementId) {
        //查询是否意见点赞
        String key = Constants.COMMENT_INTERACT_KEY + movementId;
        String redisKey = Constants.COMMENT_LIKE_HASHKEY + UserHolder.getUserId();
        Boolean aBoolean = redisTemplate.opsForHash().hasKey(key, redisKey);
        if (!aBoolean){
            throw new BusinessException(ErrorResult.disLikeError());
        }
        //调用api保存点赞数据
        Integer count = commentApi.disLike(movementId);
        //调用redis方法
        redisTemplate.opsForHash().delete(key, redisKey);
        return count;
    }
}
